const fs = require("fs");
const path = require("path");
const { execSync } = require("child_process");
const { createVideoWithFFmpeg } = require("./create_video_with_ffmpeg");
const { loadConfig } = require("./utils/config");
const { calculateDatDuration } = require("./convert_dat_to_ass"); // 添加导入
const { FFMPEG_PATH } = require("./utils/ffmpeg");
const { showCreateVideoHelp } = require("./utils/create_video_help");

// 读取配置文件
const config = loadConfig();

// 确保配置项存在，如果不存在则使用默认值
const outputDirVideo = config.outputDirVideo || "./output/videos";
const inputDirMp3 = config.inputDirMp3 || "./input/mp3";
const outputDirSrt = config.outputDirSrt || "./temp/srt";
const inputDirImages = config.inputDirImages || "./temp/imgs";
const inputDirDat = config.inputDirDat || "./input/dat"; // 添加DAT目录配置

// 获取命令行参数
const args = process.argv.slice(2);

if (args.length < 2 || args.includes("-h") || args.includes("--help")) {
  showCreateVideoHelp();
  process.exit(0);
}

// 检查第一个参数是否为完整路径
const audioArg = args[0];
const subtitleNum = args[1];

let audioFile;
let audioBaseNameForDat; // 用于查找DAT文件的基础名称

// 如果第一个参数是完整路径且文件存在，则直接使用
if (path.isAbsolute(audioArg) && fs.existsSync(audioArg)) {
  audioFile = audioArg;
  audioBaseNameForDat = path.basename(audioArg, path.extname(audioArg));
} else {
  // 否则按照原来的逻辑处理
  audioFile = path.join(__dirname, `../${inputDirMp3}`, `${audioArg}.mp3`);
  audioBaseNameForDat = audioArg;
}

// 解析选项
let imageFiles = [];
// 获取基础文件名（用于输出文件名）
const baseName = path.basename(audioFile, path.extname(audioFile));
let outputFilename = `${baseName}.mp4`;
let autoImages = false;
let useDatDuration = false; // 添加使用DAT时长的选项

for (let i = 2; i < args.length; i++) {
  const arg = args[i];
  if (arg === "-i" || arg === "--images") {
    if (i + 1 < args.length) {
      imageFiles = args[i + 1].split(",");
      i++; // 跳过下一个参数
    }
  } else if (arg === "-a" || arg === "--auto-images") {
    autoImages = true;
  } else if (arg === "-o" || arg === "--output") {
    if (i + 1 < args.length) {
      outputFilename = args[i + 1];
      i++; // 跳过下一个参数
    }
  } else if (arg === "-d" || arg === "--use-dat-duration") {
    useDatDuration = true;
  }
}

// 使用ASS字幕文件而不是SRT文件
const subtitleFile = path.join(__dirname, `../${outputDirSrt}`, `${subtitleNum}.ass`);

// 检查必需文件是否存在
if (!fs.existsSync(audioFile)) {
  console.error(`！！！错误: 音频文件不存在: ${audioFile}`);
  process.exit(1);
}

if (!fs.existsSync(subtitleFile)) {
  console.error(`！！！错误: 字幕文件不存在: ${subtitleFile}`);
  process.exit(1);
}

// 处理图片文件
let fullImagePaths = [];
const Exts = [".jpg", ".jpeg", ".png", ".bmp", ".mp4", ".mov", ".avi", ".mkv"];
if (autoImages) {
  // 自动使用imgs目录下的所有媒体文件
  const imgsDir = path.join(__dirname, `../${inputDirImages}`);
  if (fs.existsSync(imgsDir)) {
    const files = fs.readdirSync(imgsDir).filter(file => {
      const ext = path.extname(file).toLowerCase();
      // 支持图片和视频文件
      return Exts.includes(ext);
    });

    fullImagePaths = files.map(file => path.join(imgsDir, file));
    console.log(`自动检测到 ${fullImagePaths.length} 个媒体文件`);
  } else {
    console.log("警告: imgs目录不存在");
  }
} else if (imageFiles.length > 0) {
  // 使用指定的媒体文件
  fullImagePaths = imageFiles.map(file => path.resolve(file));
} else {
  console.error("！！！错误: 请指定图片文件或使用 -a 参数自动检测图片");
  process.exit(1);
}

// 检查媒体文件是否存在
for (const imgPath of fullImagePaths) {
  if (!fs.existsSync(imgPath)) {
    console.error(`！！！错误: 媒体文件不存在: ${imgPath}`);
    process.exit(1);
  }
}

// 检查并裁切不符合视频宽高比的图片
const { videoWidth, videoHeight } = config.projectSettings;
const videoAspectRatio = videoWidth / videoHeight;

for (const imgPath of fullImagePaths) {
  try {
    // 检查文件是否为视频文件，如果是则跳过裁切
    const fileExt = path.extname(imgPath).toLowerCase();
    const isVideo = [".mp4", ".mov", ".avi", ".mkv"].includes(fileExt);

    if (isVideo) {
      console.log(`  --跳过视频文件裁切: ${imgPath}`);
      continue;
    }

    // 获取图片信息
    const command = `"${FFMPEG_PATH}" -i "${imgPath}" 2>&1 | findstr "Video:"`;
    const output = execSync(command, { encoding: "utf-8" });

    // 解析图片尺寸
    const sizeMatch = output.match(/(\d+)x(\d+)/);
    if (sizeMatch) {
      const width = parseInt(sizeMatch[1]);
      const height = parseInt(sizeMatch[2]);
      const imageAspectRatio = width / height;

      // 检查图片宽高比是否与视频宽高比一致
      if (Math.abs(imageAspectRatio - videoAspectRatio) > 0.01) {
        // 允许小数点误差
        console.log(`  --裁切图片以匹配视频宽高比: ${imgPath}`);

        let cropWidth, cropHeight, cropX, cropY;

        // 根据图片和视频的宽高比决定裁切方式
        if (imageAspectRatio > videoAspectRatio) {
          // 图片更宽，裁切左右边缘
          cropHeight = height;
          cropWidth = Math.floor(height * videoAspectRatio);
          // 确保裁切宽度不超过原图宽度
          cropWidth = Math.min(cropWidth, width);
          cropX = Math.floor((width - cropWidth) / 2);
          cropY = 0;
        } else {
          // 图片更高，裁切上下边缘
          cropWidth = width;
          cropHeight = Math.floor(width / videoAspectRatio);
          // 确保裁切高度不超过原图高度
          cropHeight = Math.min(cropHeight, height);
          cropX = 0;
          cropY = Math.floor((height - cropHeight) / 2);
        }

        // 确保裁切参数有效
        if (cropWidth > 0 && cropHeight > 0 && cropX >= 0 && cropY >= 0) {
          // 执行裁切操作，使用临时文件避免覆盖问题
          const tempDir = path.join(__dirname, "../temp");
          if (!fs.existsSync(tempDir)) {
            fs.mkdirSync(tempDir, { recursive: true });
          }

          const tempPath = path.join(tempDir, `temp_crop_${Date.now()}_${path.basename(imgPath)}`);
          const cropCommand = `"${FFMPEG_PATH}" -y -i "${imgPath}" -vf "crop=${cropWidth}:${cropHeight}:${cropX}:${cropY}" "${tempPath}"`;

          // 执行裁切
          execSync(cropCommand, { stdio: "ignore" });

          // 用裁切后的图片替换原图片
          fs.copyFileSync(tempPath, imgPath);
          fs.unlinkSync(tempPath);
        } else {
          console.warn(`  跳过无效的裁切参数: width=${cropWidth}, height=${cropHeight}, x=${cropX}, y=${cropY}`);
        }
      }
    }
  } catch (error) {
    console.warn(`检查或裁切图片时出错: ${imgPath}`, error.message);
  }
}

// 输出文件路径
const outputDir = path.join(__dirname, `../${outputDirVideo}`);
const outputPath = path.join(outputDir, outputFilename);

// 确保输出目录存在
if (!fs.existsSync(outputDir)) {
  fs.mkdirSync(outputDir, { recursive: true });
}

// 计算DAT文件时长（如果需要）
let datDuration = null;
if (useDatDuration) {
  // 如果音频参数是完整路径，则尝试在相同目录查找DAT文件
  let datFile;
  // 批量处理，对于通过run_video_batch.js调用
  if (path.isAbsolute(audioArg) && fs.existsSync(audioArg)) {
    // 获取MP3文件的目录名（如"商务英语300句"）
    const mp3Dir = path.dirname(audioArg);
    const mp3BaseDir = path.basename(mp3Dir); // 子目录名
    const fn = `${audioBaseNameForDat}.dat`;
    // 构建对应的DAT文件路径
    datFile = path.join(__dirname, `../${inputDirDat}`, mp3BaseDir, fn);
  } else {
    // 原有逻辑 - 直接在inputDirDat目录下查找
    const fn = `${audioBaseNameForDat}.dat`;
    datFile = path.join(__dirname, `../${inputDirDat}`, fn);
  }

  if (fs.existsSync(datFile)) {
    datDuration = calculateDatDuration(datFile);
    console.log(`  DAT文件时长: ${datDuration} 秒`);
  } else {
    console.warn(`警告: DAT文件不存在: ${datFile}，将使用音频时长`);
    console.log(`尝试查找的DAT文件路径: ${datFile}`);
  }
}

console.log("开始创建视频,使用如下资源...");
console.log(`  音频: ${audioFile}`);
console.log(`  字幕: ${subtitleFile}`);
console.log(`  媒体文件数量: ${fullImagePaths.length}`);
console.log(`  输出: ${outputPath}`);

// 创建视频，传递DAT时长参数
createVideoWithFFmpeg(audioFile, subtitleFile, fullImagePaths, outputPath, datDuration)
  .then(() => {
    console.log("\n✅ 视频创建成功！");
  })
  .catch(error => {
    console.error("！！！创建视频时出错:", error.message);
    process.exit(1);
  });
